package com.haima.ziliao.controller;

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.haima.common.core.controller.BaseController;
import com.haima.common.utils.DateUtils;
import com.haima.common.utils.poi.ExcelUtil;
import com.haima.utils.OrderNotice;
import com.haima.utils.WeChatConstant;
import com.haima.ziliao.domain.*;
import com.haima.ziliao.service.*;
import com.wechat.pay.contrib.apache.httpclient.auth.PrivateKeySigner;
import com.wechat.pay.contrib.apache.httpclient.auth.Verifier;
import com.wechat.pay.contrib.apache.httpclient.auth.WechatPay2Credentials;
import com.wechat.pay.contrib.apache.httpclient.cert.CertificatesManager;
import com.wechat.pay.contrib.apache.httpclient.notification.Notification;
import com.wechat.pay.contrib.apache.httpclient.notification.NotificationHandler;
import com.wechat.pay.contrib.apache.httpclient.notification.NotificationRequest;
import com.wechat.pay.java.core.util.PemUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.ClassPathResource;
import org.springframework.web.bind.annotation.*;

import javax.annotation.PostConstruct;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import java.security.PrivateKey;
import java.util.Date;
import java.util.List;
import java.util.Locale;

@Slf4j
@RestController
@RequestMapping("/ziliao/callback")
public class PayCallBack extends BaseController {

    @Autowired
    private IPOrdersService ordersService;
    @Autowired
    private IPUservipService ipUservipService;
    @Autowired
    private IPDayinOrderService dayinOrderService;
    @Autowired
    private IPDuwuService duwuService;
    @Autowired
    private IPMyduwuService myduwuService;
    @Autowired
    private IPVipconfigService vipconfigService;

    private CertificatesManager certificatesManager;

    public static ClassPathResource resourcePrivateKey = new ClassPathResource(WeChatConstant.PRIVATE_KEY_PATH);

    @PostConstruct
    public void init() throws Exception {
        //获取商户私钥
        PrivateKey merchantPrivateKey = PemUtil.loadPrivateKeyFromString("-----BEGIN PRIVATE KEY-----\n" +
                "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDaVxx2leGFkbmk\n" +
                "u0vu8woRPTY8UhiGUsAy4fgPi1uttUsCuuuZEpYJxeTU1Ha5GvbVvX2LJn6UiQJ5\n" +
                "c0yTBsJpkGrKqXzAD3musPGxG+T1xAv3HwfIkRz7ePk/mLvAIITYwNa+TLNhS5IE\n" +
                "VDbbpNDGK5MER0kCIBTpD45YQoVzVeUIuZqh4OreZ4uQ7VgaO12T3XcJW2ZqDBI5\n" +
                "eoz4RHUotoBsB7Xwq8tIGBPn5hR8mXFT3mYnZj4hfFRN+dyMfKxldrSZeMt58QVf\n" +
                "wbACLk2xkXoUT1NdlnzZS+qH88lDnf0oO+iHCDOmfmD2YdtXTi9A244tnAnW/nzV\n" +
                "vexjf0vrAgMBAAECggEAVJkmFSiTvj4tcQ+FJ2uR/gX6qrqgeAM+Jzj49YTom9C/\n" +
                "5KnqOWBDNDwyIujDq4swErceGrlqmEDR7Z7oD5ux3lcvmaC8DmqwmihDLX2CZFt2\n" +
                "y2SBjovzb9h6stKKBLJU5uspCYkMg+lVBUpgCxC8N9yQVTsNpb4qe/ckDzyPGpV5\n" +
                "Lrlnsl8iiBMVKuPpscFBNtC3nGKahOs92mkptOuICdevf6Lfp14vPIr/or2egPhY\n" +
                "f6yCywDwdUbuO3xBye39UK4PtTKfYd4YdS/46eFibvnhpzMaQIwhrxqsb+v3Scgl\n" +
                "ws4FFIecUQQGXOdDU52nZtl/IOapa5VnbmurV9QEmQKBgQDxHTT+CwAuK+NtD1cI\n" +
                "EK/c/4weV00I0H0Aw+BwagCltIg9lJurN96ZGz3YiHe7rq6Mm7cRTlvoHqOUmDOW\n" +
                "8bvyHDLAonhvPOY1FZ9xWqb4UCUK2kcwtGQ8G+h6gKcoJMPu772du0v5oAo1btVM\n" +
                "YAYySMq4tq81MvYRhjoasCEtnwKBgQDn0fcsfsZQfYLoLVryX40GXtiYh9pLqNhI\n" +
                "UQGEOR/CX9QzD4gyVv4GV/BCHB/PNLM9HSkHz0tTrhuLO0d0JiRkH27080IBW9ON\n" +
                "tVisgQ34Eo18RXd4nAF8ewITLorpL41uN6YQnrRIspUKw+kvZPVPOBMIJoHIJbQB\n" +
                "qHaQd9zmNQKBgDoPI2SM95UmolPvnrBlfEOGEZJ4ySb3NTKK+C95hwBf0XKqpzV6\n" +
                "dZJ+mczbR6Gc9ZEMKe/z43OodRFh+QI+4VfybFIwjTmT+4cK1uLvxkcC3XiYiQ30\n" +
                "UjKbMcbV1ep3t+qANjOWFzxbyjmFn70NXlCbcJ07+EKiK9iabsFgagzXAoGAJ7r0\n" +
                "gcu4cVMRfHlJfQCjStQ2iu29m/n0F3DKsb6YkteZpqai0P3Xy36Gzs3DJeACWBcH\n" +
                "US9V2aGdVt9x/5YJ5p78hT6rsU/rkf3ilK4JltqXJRVCxIj4OD1cvazcYdqkgp9G\n" +
                "9tI8U7lHkfDBpj3HTSxvFpaC56qOjzowF9JzKYECgYBKTQNLOE0yHkj/JELwbHXi\n" +
                "sF0U8mv+aKtKqFY1xYxtbmnG3DcpmzETmSJloSl7X0vPB5mKpgOLax2698fqN0d/\n" +
                "OZdWTKp9Jr72HFT41vh/tw7aHr0hlf+/b2kqLGYnlpaKtAyl+E/rtQYzGNCcpNuS\n" +
                "ERJihYuM5ACj9/JC2y1aWg==\n" +
                "-----END PRIVATE KEY-----\n");
        certificatesManager = CertificatesManager.getInstance();

        //向证书管理器增加需要自动更新平台证书的商户信息
        certificatesManager.putMerchant(WeChatConstant.MERCHANT_ID, new WechatPay2Credentials(WeChatConstant.MERCHANT_ID,
                        new PrivateKeySigner(WeChatConstant.MERCHANT_SERIALNUMBER, merchantPrivateKey)),
                WeChatConstant.API_V3_KEY.getBytes(StandardCharsets.UTF_8));
        //从证书获取verifier
        Verifier verifier = certificatesManager.getVerifier(WeChatConstant.MERCHANT_ID);
    }


    @PostMapping("/vipCallBack")
    public void vipCallBack(HttpServletRequest request, HttpServletResponse response) {
        String characterEncoding = request.getCharacterEncoding();

        //从请求头获取验签字段
        String timeStamp = request.getHeader("Wechatpay-Timestamp");
        String nonce = request.getHeader("Wechatpay-Nonce");
        String signature = request.getHeader("Wechatpay-Signature");
        String certSn = request.getHeader("Wechatpay-Serial");

        log.info("wx callback params,timesStamp:{},nonce:{},signature:{},certSn:{}", timeStamp, nonce, signature, certSn);
        try(BufferedReader reader = new BufferedReader(new
                InputStreamReader(request.getInputStream()))) {
            StringBuilder sb = new StringBuilder();
            String line;
            while ((line = reader.readLine()) != null) {
                sb.append(line);
            }
            String body = sb.toString();
            //检验签名
            Verifier verifier = certificatesManager.getVerifier(WeChatConstant.MERCHANT_ID);
            String sn = verifier.getValidCertificate().getSerialNumber().toString(16).toUpperCase(Locale.ROOT);
            NotificationRequest notifyRequest = new NotificationRequest.Builder().withSerialNumber(sn)
                    .withNonce(nonce)
                    .withTimestamp(timeStamp)
                    .withSignature(signature)
                    .withBody(body)
                    .build();
            NotificationHandler handler = new NotificationHandler(verifier, WeChatConstant.API_V3_KEY.getBytes(StandardCharsets.UTF_8));

            //验证和解析请求体
            Notification notification = handler.parse(notifyRequest);

            log.info("wx callback response:{}", JSON.toJSONString(notification));
            JSONObject res = JSON.parseObject(notification.getDecryptData());
            String outTradeNo = res.getString("out_trade_no");
            String transactionId = res.getString("transaction_id");
            String tradeState = res.getString("trade_state");
            String tradeStateDesc = res.getString("trade_state_desc");
            String successTime = res.getString("success_time");

            //处理相关业务
            if("SUCCESS".equals(tradeState)){
                POrders orders = ordersService.getOne(new QueryWrapper<POrders>().eq("orderNum",outTradeNo));

                PVipconfig vc = vipconfigService.selectPVipconfigById(orders.getBid());

                orders.setStatus("2");
                orders.setPayInfo(notification.getDecryptData());
                orders.setPayTime(successTime);
                orders.setWxNum(transactionId);
                ordersService.updatePOrders(orders);

                //处理VIP信息
                Long uid = orders.getUid();
                PUservip vip = ipUservipService.getOne(new QueryWrapper<PUservip>().eq("uid",uid));

                if(vip==null){//新增VIP
                    PUservip nvip = new PUservip();
                    nvip.setUid(uid);
                    nvip.setStartTime(DateUtils.getNowDate());
                    nvip.setEndTime(DateUtils.addDays(nvip.getStartTime(),vc.getDays()));
                    nvip.setStatus("1");
                    nvip.setType("1");
                    ipUservipService.insertPUservip(nvip);
                }else{
                    Date endTime = vip.getEndTime();
                    vip.setStatus("1");

                    if(endTime.before(DateUtils.getNowDate())){//如果当前时间大于结束时间，则从今日开始续费
                        vip.setEndTime(DateUtils.addDays(DateUtils.getNowDate(),vc.getDays()));
                    }else if(endTime.after(DateUtils.getNowDate())){//如果当前时间小于结束时间，则从结束时间开始续费
                        vip.setEndTime(DateUtils.addDays(endTime,vc.getDays()));
                    }else {//如果当前时间等于结束时间，则无所谓
                        vip.setEndTime(DateUtils.addDays(DateUtils.getNowDate(),vc.getDays()));
                    }
                    ipUservipService.updatePUservip(vip);
                }
            }
            //响应微信服务器
            response.setStatus(200);
            JSONObject jsonObject = new JSONObject();
            jsonObject.put("code", "SUCCESS");
            jsonObject.put("message", "SUCCESS");
            response.getOutputStream().write(jsonObject.toJSONString().getBytes(StandardCharsets.UTF_8));
            response.flushBuffer();
        } catch (Exception e) {
            log.error("wx callback error", e);
            response.setStatus(500);
            JSONObject jsonObject = new JSONObject();
            jsonObject.put("code", "ERROR");
            jsonObject.put("message", "签名失败");
            try {
                response.getOutputStream().write(jsonObject.toJSONString().getBytes(StandardCharsets.UTF_8));
                response.flushBuffer();
            } catch (Exception ex) {
                log.error("微信回调失败",e);
            }
        }
    }


    @PostMapping("/dayinCallBack")
    public void dayinCallBack(HttpServletRequest request, HttpServletResponse response) {
        String characterEncoding = request.getCharacterEncoding();

        //从请求头获取验签字段
        String timeStamp = request.getHeader("Wechatpay-Timestamp");
        String nonce = request.getHeader("Wechatpay-Nonce");
        String signature = request.getHeader("Wechatpay-Signature");
        String certSn = request.getHeader("Wechatpay-Serial");

        log.info("wx callback params,timesStamp:{},nonce:{},signature:{},certSn:{}", timeStamp, nonce, signature, certSn);
        try(BufferedReader reader = new BufferedReader(new
                InputStreamReader(request.getInputStream()))) {
            StringBuilder sb = new StringBuilder();
            String line;
            while ((line = reader.readLine()) != null) {
                sb.append(line);
            }
            String body = sb.toString();
            //检验签名
            Verifier verifier = certificatesManager.getVerifier(WeChatConstant.MERCHANT_ID);
            String sn = verifier.getValidCertificate().getSerialNumber().toString(16).toUpperCase(Locale.ROOT);
            NotificationRequest notifyRequest = new NotificationRequest.Builder().withSerialNumber(sn)
                    .withNonce(nonce)
                    .withTimestamp(timeStamp)
                    .withSignature(signature)
                    .withBody(body)
                    .build();
            NotificationHandler handler = new NotificationHandler(verifier, WeChatConstant.API_V3_KEY.getBytes(StandardCharsets.UTF_8));

            //验证和解析请求体
            Notification notification = handler.parse(notifyRequest);

            log.info("wx callback response:{}", JSON.toJSONString(notification));
            JSONObject res = JSON.parseObject(notification.getDecryptData());
            String outTradeNo = res.getString("out_trade_no");
            String transactionId = res.getString("transaction_id");
            String tradeState = res.getString("trade_state");
            String tradeStateDesc = res.getString("trade_state_desc");
            String successTime = res.getString("success_time");

            //处理相关业务
            if("SUCCESS".equals(tradeState)){
                POrders orders = ordersService.getOne(new QueryWrapper<POrders>().eq("orderNum",outTradeNo));
                orders.setStatus("2");
                orders.setPayInfo(notification.getDecryptData());
                orders.setPayTime(successTime);
                orders.setWxNum(transactionId);
                ordersService.updatePOrders(orders);

                //处理打印信息
                Long id = orders.getBid();
                PDayinOrder dyorder = dayinOrderService.selectPDayinOrderById(id);

                dyorder.setStatus("2");
                dyorder.setIspay("1");
                dyorder.setOid(orders.getId());
                dayinOrderService.updatePDayinOrder(dyorder);

                JSONArray jar = JSONArray.parseArray(dyorder.getFilespath());

                String content="新打印订单，请及时处理\n"
                        +"收件人："+dyorder.getName()
                        +"\n联系电话：<font color=\"comment\">"+dyorder.getPhone()+"</font>"
                        +"\n收件地址："+dyorder.getAddr()
                        +"\n创建时间："+dyorder.getAddTime()+"\n\n";

                for(int i=0;i<jar.size();i++){
                    JSONObject jo = jar.getJSONObject(i);

                    content += "\n文件名称："+jo.get("name");
                    String gs = jo.getString("geshi");
                    JSONObject gejson = JSONObject.parseObject(gs);
                    content += "\n份数："+jo.get("fs");
                    content += "\n单双面："+gejson.get("danshuang");
                    content += "\n颜色："+gejson.get("leixing");
                    content += "\n装订方式："+gejson.get("zhuangding")+"\n\n";
                }

                OrderNotice.sendMsgMarkDown(content);


            }
            //响应微信服务器
            response.setStatus(200);
            JSONObject jsonObject = new JSONObject();
            jsonObject.put("code", "SUCCESS");
            jsonObject.put("message", "SUCCESS");
            response.getOutputStream().write(jsonObject.toJSONString().getBytes(StandardCharsets.UTF_8));
            response.flushBuffer();
        } catch (Exception e) {
            log.error("wx callback error", e);
            response.setStatus(500);
            JSONObject jsonObject = new JSONObject();
            jsonObject.put("code", "ERROR");
            jsonObject.put("message", "签名失败");
            try {
                response.getOutputStream().write(jsonObject.toJSONString().getBytes(StandardCharsets.UTF_8));
                response.flushBuffer();
            } catch (Exception ex) {
                log.error("微信回调失败",e);
            }
        }
    }


    @GetMapping("/testMsg/{id}")
    public void testMsg(@PathVariable("id") Long id) {
        PDayinOrder dyorder = dayinOrderService.selectPDayinOrderById(id);

        JSONArray jar = JSONArray.parseArray(dyorder.getFilespath());

        String content="新打印订单，请及时处理\n"
                +"收件人："+dyorder.getName()
                +"\n联系电话：<font color=\"comment\">"+dyorder.getPhone()+"</font>"
                +"\n收件地址："+dyorder.getAddr()
                +"\n创建时间："+dyorder.getAddTime()+"\n\n";

        for(int i=0;i<jar.size();i++){
            JSONObject jo = jar.getJSONObject(i);

            content += "\n文件名称："+jo.get("name");
            String gs = jo.getString("geshi");
            JSONObject gejson = JSONObject.parseObject(gs);
            content += "\n单双面："+gejson.get("danshuang");
            content += "\n颜色："+gejson.get("leixing");
            content += "\n装订方式："+gejson.get("zhuangding")+"\n\n";
        }

        OrderNotice.sendMsgMarkDown(content);
    }


    @PostMapping("/duwuCallBack")
    public void duwuCallBack(HttpServletRequest request, HttpServletResponse response) {
        String characterEncoding = request.getCharacterEncoding();

        //从请求头获取验签字段
        String timeStamp = request.getHeader("Wechatpay-Timestamp");
        String nonce = request.getHeader("Wechatpay-Nonce");
        String signature = request.getHeader("Wechatpay-Signature");
        String certSn = request.getHeader("Wechatpay-Serial");

        log.info("wx callback params,timesStamp:{},nonce:{},signature:{},certSn:{}", timeStamp, nonce, signature, certSn);
        try(BufferedReader reader = new BufferedReader(new
                InputStreamReader(request.getInputStream()))) {
            StringBuilder sb = new StringBuilder();
            String line;
            while ((line = reader.readLine()) != null) {
                sb.append(line);
            }
            String body = sb.toString();
            //检验签名
            Verifier verifier = certificatesManager.getVerifier(WeChatConstant.MERCHANT_ID);
            String sn = verifier.getValidCertificate().getSerialNumber().toString(16).toUpperCase(Locale.ROOT);
            NotificationRequest notifyRequest = new NotificationRequest.Builder().withSerialNumber(sn)
                    .withNonce(nonce)
                    .withTimestamp(timeStamp)
                    .withSignature(signature)
                    .withBody(body)
                    .build();
            NotificationHandler handler = new NotificationHandler(verifier, WeChatConstant.API_V3_KEY.getBytes(StandardCharsets.UTF_8));

            //验证和解析请求体
            Notification notification = handler.parse(notifyRequest);

            log.info("wx callback response:{}", JSON.toJSONString(notification));
            JSONObject res = JSON.parseObject(notification.getDecryptData());
            String outTradeNo = res.getString("out_trade_no");
            String transactionId = res.getString("transaction_id");
            String tradeState = res.getString("trade_state");
            String tradeStateDesc = res.getString("trade_state_desc");
            String successTime = res.getString("success_time");

            //处理相关业务
            if("SUCCESS".equals(tradeState)){
                POrders orders = ordersService.getOne(new QueryWrapper<POrders>().eq("orderNum",outTradeNo));
                orders.setStatus("2");
                orders.setPayInfo(notification.getDecryptData());
                orders.setPayTime(successTime);
                orders.setWxNum(transactionId);
                ordersService.updatePOrders(orders);

                PDuwu dw = duwuService.selectPDuwuById(orders.getBid());

                //处理VIP信息
                PMyduwu pmd = new PMyduwu();
                Long uid = orders.getUid();
                pmd.setUid(uid);
                pmd.setBuytime(orders.getAddTime());
                pmd.setDid(orders.getBid());
                pmd.setTitle(dw.getTitle());
                pmd.setDownloadurl(dw.getPath());
                myduwuService.insertPMyduwu(pmd);
            }
            //响应微信服务器
            response.setStatus(200);
            JSONObject jsonObject = new JSONObject();
            jsonObject.put("code", "SUCCESS");
            jsonObject.put("message", "SUCCESS");
            response.getOutputStream().write(jsonObject.toJSONString().getBytes(StandardCharsets.UTF_8));
            response.flushBuffer();
        } catch (Exception e) {
            log.error("wx callback error", e);
            response.setStatus(500);
            JSONObject jsonObject = new JSONObject();
            jsonObject.put("code", "ERROR");
            jsonObject.put("message", "签名失败");
            try {
                response.getOutputStream().write(jsonObject.toJSONString().getBytes(StandardCharsets.UTF_8));
                response.flushBuffer();
            } catch (Exception ex) {
                log.error("微信回调失败",e);
            }
        }
    }

}
